import tinycolor, { ColorFormats } from 'tinycolor2';

export type ChromaOption = {
  length: number;
  lightColorCount: number;
  hueStep: number;
  saturationStep: number;
  saturationStep2: number;
  darkColorCount: number;
  brightnessStep1: number;
  brightnessStep2: number;
}

/** 获取色阶
 * @param color 颜色
 * @param length 色阶长度
 * @param offset 基准色偏移量，负数向左，正数向右，仅正整数，小数将被省略
 */
export default (color: string) => {
  const hex = tinycolor(color).toHex();
  const rgb = tinycolor(color).toRgb();
  const hsl = tinycolor(color).toHsl();
  const hsv = tinycolor(color).toHsv();

  return {
    hex,
    rgb,
    hsl,
    hsv,
    /** 生成梯度色号
     * @param option
     */
    getChromaLevel({
      length = 10,
      lightColorCount = 6,
      hueStep = length / 10,
      saturationStep = length / 15,
      saturationStep2 = length / 20,
      darkColorCount = length / 4,
      brightnessStep1 = length / 5,
      brightnessStep2 = length / 15,
    }: Partial<ChromaOption>) {
      /** 计算结果 */
      const colors: string[] = [];
      /** 获取色相渐变 */
      const getHue = (hsv: ColorFormats.HSVA, i: number, isLight: boolean) => {
        if (hsv.h >= 60 && hsv.h <= 240) {
          // 冷色调
          // 减淡变亮 色相顺时针旋转 更暖
          // 加深变暗 色相逆时针旋转 更冷
          return isLight ? hsv.h - hueStep * i : hsv.h + hueStep * i;
        } else {
          // 暖色调
          // 减淡变亮 色相逆时针旋转 更暖
          // 加深变暗 色相顺时针旋转 更冷
          return isLight ? hsv.h + hueStep * i : hsv.h - hueStep * i;
        }
      };
      /** 获取饱和度渐变 */
      const getSaturation = (hsv: ColorFormats.HSVA, i: number, isLight: boolean) => {
        if (isLight) {
          // 减淡变亮 饱和度迅速降低
          return Math.round(hsv.s * 100) - saturationStep * i;
        } else if (i == darkColorCount) {
          // 加深变暗-最暗 饱和度提高
          return Math.round(hsv.s * 100) + saturationStep;
        } else {
          // 加深变暗 饱和度缓慢提高
          return Math.round(hsv.s * 100) + saturationStep2 * i;
        }
      };
      /** 获取亮度渐变 */
      const getValue = (hsv: ColorFormats.HSVA, i: number, isLight: boolean) => {
        // 减淡变亮
        if (isLight) return Math.round(hsv.v * 100) + brightnessStep1 * i;
        // 加深变暗幅度更大
        else return Math.round(hsv.v * 100) - brightnessStep2 * i;
      };
      /** 获取色阶 */
      const getChroma = (hsv: ColorFormats.HSVA, index: number) => {
        let isLight = index <= lightColorCount;
        let i = isLight ? lightColorCount + 1 - index : index - lightColorCount - 1;
        return tinycolor({
          h: getHue(hsv, i, isLight),
          s: getSaturation(hsv, i, isLight),
          v: getValue(hsv, i, isLight),
        }).toHexString();
      };
      for (let i = 0; i < length; i++) {
        colors.push(getChroma(hsv, i))
      }
      // console.log(length, colors);
      return colors;
    },
  };
};
